package eu.codlab.twitteirb;

import java.util.ArrayList;
import java.util.Random;

import eu.codlab.twitteirb.manage.OnMessageReceiveListener;
import eu.codlab.twitteirb.manage.SendTweetListener;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Handler;
import android.os.IBinder;

public class TwittEirbService extends Service implements SendTweetListener, OnSharedPreferenceChangeListener{
	private final static String PREFERENCES = "eu.codlab.twitteirb_preferences";
	private final static String PREFERENCES_INTERVAL_LISTENER_ON="interval_listener_on";
	private final static String PREFERENCES_INTERVAL_LISTENER_OFF="interval_listener_off";
	private final static String PREFERENCES_SERVICE_RESTART="service_restart";
	
	private int _wait_interval_on;
	private int _wait_interval_off;
	private boolean _service_behaviour;
	
	
	private static TwittEirbService _this;
	private ArrayList<OnMessageReceiveListener> _listeners;
	private CookieManager _cookie;
	private MessageManager _message_manager;
	private LoginManager _login_manager;
	private AvatarManager _avatar_manager;
	//private String _last_id;
	private ArrayList<Tweet> _tweets;
	private ArrayList<String> _connectes;
	private Handler _handler;
	private boolean _valid;
	private int _unread;
	private int _notif;
	private String _login;
	private boolean _is_loading=false;
	private SendTweetType _sendtweet;

	private enum SendTweetType{
		NONE,SEND,SENDALL;
	}

	private int NOTIFICATION_TWEETS=0;
	//private int NOTIFICATION_STATE=1;
	//private int NOTIFICATION_SEND=2;

	public static TwittEirbService getService(){
		return _this;
	}

	@Override
	public IBinder onBind(Intent arg0) {
		return null;
	}

	@Override
	public void onCreate(){
		_this = this;
		_sendtweet=SendTweetType.NONE;
		connectState(TwittEirbConnect.LOGOFF);
		_valid = false;
		_unread=0;
		Random r = new Random(System.currentTimeMillis());
		this.getSharedPreferences(TwittEirbActivity.PREF, 0).edit().putString(TwittEirbActivity.FIELD, Integer.toString(r.nextInt())).commit();
		
		
		SharedPreferences settings = this.getSharedPreferences(PREFERENCES, 0);
		if(settings != null){
			_service_behaviour = settings.getBoolean(PREFERENCES_SERVICE_RESTART, false);
			_wait_interval_off = settings.getInt(PREFERENCES_INTERVAL_LISTENER_OFF, 5)*60000;
			_wait_interval_on = settings.getInt(PREFERENCES_INTERVAL_LISTENER_ON, 1)*60000;
			settings.registerOnSharedPreferenceChangeListener(this);
		}else{
			_service_behaviour = true;
			_wait_interval_off = 5*60000;
			_wait_interval_on = 1*60000;
		}
		
		super.onCreate();
		
		
	}

	private void check(){
		if(_handler == null)
			_handler = new Handler();
		if(_cookie == null)
			_cookie = new CookieManager();
		if(_listeners == null)
			_listeners = new ArrayList<OnMessageReceiveListener>();
		if(_message_manager == null)
			_message_manager = new MessageManager(this.getApplicationContext(), this, _cookie);
		if(_login_manager == null)
			_login_manager = new LoginManager(this.getApplicationContext(), this, _cookie);
		if(_tweets == null)
			_tweets = new ArrayList<Tweet>();
		if(_avatar_manager == null)
			_avatar_manager = new AvatarManager(this);
		if(_connectes == null)
			_connectes = new ArrayList<String>();
	}

	public boolean bindListener(OnMessageReceiveListener listener){
		check();
		if(!_listeners.contains(listener)){
			_listeners.add(listener);
			return true;
		}
		return false;
	}

	public void unbindListener(OnMessageReceiveListener listener){
		check();
		if(_listeners.contains(listener))
			_listeners.remove(listener);
	}



	@Override
	public int onStartCommand(Intent intent, int flags, int startId){
		_this= this;

		//setLoginFromAccount();
		try{
		SharedPreferences settings = this.getSharedPreferences(PREFERENCES, 0);
		if(settings != null){
			_service_behaviour = settings.getBoolean(PREFERENCES_SERVICE_RESTART, false);
		}
		}catch(Exception e){
			_service_behaviour = false;
		}
		if(this._service_behaviour)
			return Service.START_STICKY;
		else
			return Service.START_NOT_STICKY;
	}

	public void onLoginOK(String cookie, String trombi){
		connectState(TwittEirbConnect.LOGGED);
		log("Service","onLoginOk");
		_message_manager.go(cookie);
		_avatar_manager.setCookie(trombi);
		this._login = _login_manager.getLogin();
		_valid = true;
	}

	public void onGetMessageRedirect(){
		_is_loading=false;
		notificationTweetDelete();
		connectState(TwittEirbConnect.LOGERROR);
		_valid = false;
		log("Service","onGetMessageRedirect");
		_login_manager.go();
	}
	public void onLoginError(){
		connectState(TwittEirbConnect.LOGERROR);
		_valid = false;
		log("Service","onLoginError");
		for(OnMessageReceiveListener listener : _listeners){
			listener.onRequestLogin();
		}
	}

	public boolean getStateConnection(){
		return _valid;
	}

	public void onGetLoginString(String readStream) {
		_connectes.clear();

		if(readStream != null && readStream.indexOf("rel=\"") >=0){
			//we just received users \o/
			String [] users = readStream.split("rel=\"");
			for(int i=1;i<users.length;i++){
				_connectes.add(users[i].split("\"")[0]);
			}
		}
		for(OnMessageReceiveListener listener : _listeners){
			listener.onNewUsers(_connectes);
		}			
	}

	public void onGetMessageString(String string){
		_login = _login_manager.getLogin();
		notificationTweetDelete();
		final int w = _listeners.size()>0 ? _wait_interval_on : _wait_interval_off;
		//we register a new
		_handler.postDelayed(new Runnable(){
			@Override
			public void run(){
				if(!_is_loading){
					_is_loading=true;
					_message_manager.go();
				}
			}
		}, w);
		connectState(TwittEirbConnect.LOGGED);
		check();

		if(string.indexOf("first_id\" rel=")>0){
			//this._last_id = string.split("first_id\" rel=\"")[1].split("\"")[0];
			int i=0;
			this._message_manager.setLastId(string.split("first_id\" rel=\"")[1].split("\"")[0]);
			String [] tweets = string.split("<div class=\"tweet ");
			Tweet _ob=null;
			for(i=tweets.length-1;i>=0;i--){
				String login="";
				String date="";
				String text="";
				if(tweets[i].indexOf("/?login=")>=0 && tweets[i].indexOf("relative-date\"")>=0 && tweets[i].indexOf("class=\"text\">")>=0){
					login=tweets[i].split("/?login=")[1].substring(0,42).split("\"")[0];
					date=tweets[i].split("relative-date\"")[1].split("<br />")[0].split(">")[1];
					text=tweets[i].split("class=\"text\">")[1].split("</div>")[0];
					//Log.d("personne", login+" "+date+" "+text);
					_ob = new Tweet(login, date, text);
					if(text.indexOf("@"+_login) >=0)
						_notif++;
					_tweets.add(0, _ob);
					_unread++;

					_avatar_manager.addLogin(login);
				}
			}

			_avatar_manager.go();


			switch(_sendtweet){
			case SENDALL:
				if(_notif>0)
					_notif--;
			case SEND:
				if(_unread>0)
					_unread--;
				break;
			default:
			}

			if(_unread>0 && _notif>0){
				notification("Notifications : "+_notif+" ; "+"Non lus : "+_unread);
			}else if(_unread>0){
				notification("Non lus : "+_unread);
			}
			
			_unread++;
			if(_unread > 0)
				for(OnMessageReceiveListener listener : _listeners){
					listener.onNewMessage(_tweets);
				}
			_unread--;


		}
		_is_loading = false;

	}

	@Override
	public void onDestroy(){
		//connectState(TwittEirbConnect.SERVICEOFF);
		_login_manager=null;
		_message_manager=null;
		this.getSharedPreferences(PREFERENCES, 0).unregisterOnSharedPreferenceChangeListener(this);

		super.onDestroy();
	}
	private enum TwittEirbConnect{
		LOGOFF,LOGERROR, LOGGED,PENDING,SERVICEOFF;
	}
	TwittEirbConnect _state = TwittEirbConnect.LOGOFF;

	private void connectState(TwittEirbConnect state){
		_state = state;
		if(state != TwittEirbConnect.LOGGED){
			int text=R.string.logoff;
			int led=0xffff0000;
			switch(state){
			case LOGOFF:
				led=0xffff0000;
				text=R.string.logoff;
				break;
			case LOGERROR:
				led=0xffff0000;
				text=R.string.logerror;
				break;
			case LOGGED:
				led=0xff00ff00;
				text=R.string.logon;
				break;
			case PENDING:
				led=0xff0000ff;
				text=R.string.pedngin;
				break;
			case SERVICEOFF:
				led=0xff0000ff;
				text=R.string.logoff;
				break;
			}
			NotificationManager notificationManager = (NotificationManager) 
					getSystemService(NOTIFICATION_SERVICE);
			Notification notification = new Notification(R.drawable.ic_launcher,
					getText(text), System.currentTimeMillis());
			// Hide the notification after its selected
			if(state != TwittEirbConnect.SERVICEOFF)
				notification.flags|=Notification.FLAG_AUTO_CANCEL;
			else
				notification.flags|=Notification.FLAG_AUTO_CANCEL;
			notification.flags |= Notification.FLAG_SHOW_LIGHTS;
			notification.ledARGB=led;
			notification.ledOnMS=1;

			Intent intent = new Intent(this, TwittEirbActivity.class);
			PendingIntent activity = PendingIntent.getActivity(this, 0, intent, 0);
			notification.setLatestEventInfo(this, "TwittEirb",
					getText(text), activity);
			notification.number += 1;
			notificationManager.notify(NOTIFICATION_TWEETS, notification);
		}
	}

	private void notification(String text){

		NotificationManager notificationManager = (NotificationManager) 
				getSystemService(NOTIFICATION_SERVICE);
		Notification notification = new Notification(R.drawable.ic_launcher,
				text, System.currentTimeMillis());
		// Hide the notification after its selected
		notification.flags |= Notification.FLAG_AUTO_CANCEL;
		notification.flags |= Notification.FLAG_SHOW_LIGHTS;
		notification.ledARGB=0xff00ff00;
		notification.ledOnMS=1;

		Intent intent = new Intent(this, TwittEirbActivity.class);
		PendingIntent activity = PendingIntent.getActivity(this, 0, intent, 0);
		notification.setLatestEventInfo(this, "TwittEirb",
				text, activity);
		notification.number += 1;
		notificationManager.notify(NOTIFICATION_TWEETS, notification);
	}


	private boolean _notif_tweet=false;
	private void notificationTweet(){

		NotificationManager notificationManager = (NotificationManager) 
				getSystemService(NOTIFICATION_SERVICE);
		Notification notification = new Notification(R.drawable.ic_launcher,
				"Envoi en cours....", System.currentTimeMillis());
		// Hide the notification after its selected
		notification.flags |= Notification.FLAG_AUTO_CANCEL;
		notification.flags |= Notification.FLAG_SHOW_LIGHTS;
		notification.ledARGB=0xffff0000;
		notification.ledOnMS=1;

		Intent intent = new Intent(this, TwittEirbActivity.class);
		PendingIntent activity = PendingIntent.getActivity(this, 0, intent, 0);
		notification.setLatestEventInfo(this, "TwittEirb",
				"Envoi en cours...", activity);
		notification.number += 1;
		notificationManager.notify(NOTIFICATION_TWEETS, notification);
	}
	private void notificationTweetDelete(){
		NotificationManager notificationManager = (NotificationManager) 
				getSystemService(NOTIFICATION_SERVICE);
		notificationManager.cancel(NOTIFICATION_TWEETS);
	}
	public void go(){
		_login_manager.go();
	}

	public void setRead(){
		_notif=0;
		_unread=0;
		//notificationTweetDelete();
	}
	public void setLogin(String user, String password){
		if(_valid == false && _state != TwittEirbConnect.PENDING && _state != TwittEirbConnect.LOGGED){
			_valid=false;
			_login = user;
			_login_manager.setLogin(user, password);
			_login_manager.go();
			connectState(TwittEirbConnect.PENDING);
		}
	}

	public void setLoginFromAccount(){
		if(_valid == false && _state != TwittEirbConnect.PENDING && _state != TwittEirbConnect.LOGGED){
			_valid=false;
			_login_manager.go();
			connectState(TwittEirbConnect.PENDING);
		}
	}
	public String getLogin(){
		return _login;
	}

	public ArrayList<Tweet> getTweets(){
		return _tweets;
	}
	public ArrayList<String> getPeers(){
		return _connectes;
	}

	public void sendTweet(String tweet){
		this.notificationTweet();
		SendTweet s = new SendTweet(this,tweet, this,_message_manager.getCookie());
		s.go();
	}

	@Override
	public void onTweetSend() {
		askRefresh();
	}

	public boolean askRefresh(){
		if(_is_loading == false){
			_is_loading=true;
			_message_manager.go();
			return true;
		}
		return false;
	}

	public void onAvatarLoaded(){
		for(OnMessageReceiveListener listener : _listeners){
			listener.onAvatarLoaded();
		}
	}

	public byte[] getAvatar(String login){
		return _avatar_manager.getAvatar(login);
	}

	@Override
	public void onSharedPreferenceChanged(SharedPreferences arg0, String key) {
		log("changing settings",""+key);
		if(key.equals(this.PREFERENCES_SERVICE_RESTART)){
			_service_behaviour = arg0.getBoolean(key, false);
		}else if(key.equals(this.PREFERENCES_INTERVAL_LISTENER_OFF)){
			_wait_interval_off = arg0.getInt(key, 5)*60000;
		}else if(key.equals(this.PREFERENCES_INTERVAL_LISTENER_ON)){
			_wait_interval_on = arg0.getInt(key, 1)*60000;
		}
	}
	
	private final void log(String i1, String i2){
		
	}

}
